#include <Ogre.h>

#include "ogreconsole.h"
#include "IntroState.h"
#include "PlayState.h"
#include "NetState.h"
#include "PauseState.h"

using namespace Ogre;
using namespace std;

NetState NetState::mNetState;

void NetState::enter()
{
	mDeviceManager = DeviceManager::getSingletonPtr();
	mGUIManager = GUIManager::getSingletonPtr();
	mKeyboard = mDeviceManager->mKeyboard;
	mMouse = mDeviceManager->mMouse;
	mDeviceManager->setBuffered(true);

	// Create SceneManager
	mRoot = Root::getSingletonPtr();
	mSceneMgr = mRoot->createSceneManager(ST_GENERIC);

	// Create Camera
	mCamera = mSceneMgr->createCamera("NetCamera");

	// Create Viewport
	mViewport = mRoot->getAutoCreatedWindow()->addViewport(mCamera);
	mViewport->setBackgroundColour(ColourValue(1.0, 0.0, 0.0));

	// Reigster GUI Items
	mGUIManager->registerScene(mSceneMgr);
	mGUIManager->setGUISheet(CEGUI::WindowManager::getSingletonPtr()->getWindow("Net/Sheet"));
	
	setupEventHandlers();

	// Set default values for each entry
	mExitGame = false;
	//mGoToPlay = false;
	mCreate = false;
	mConnect = false;
	mStart = false;

	conn = new NetConsole;

}

void NetState::exit()
{
	delete conn;
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
	CEGUI::Window *text = wmgr->getWindow((CEGUI::utf8*)"Net/Text");
	text->setText("Press button to proceed\n");
	CEGUI::Window *ip = wmgr->getWindow((CEGUI::utf8*)"Net/IP");
	ip->setText("");
	CEGUI::Window *msg = wmgr->getWindow((CEGUI::utf8*)"Net/Message");
	msg->setText("");
	mSceneMgr->clearScene();
	mSceneMgr->destroyAllCameras();
	mRoot->getAutoCreatedWindow()->removeAllViewports();
}

void NetState::pause()
{
}

void NetState::resume()
{
}

bool NetState::keyPressed(const OIS::KeyEvent &arg)
{
	if (arg.key == OIS::KC_P)
		mGoToPlay = true;
	if (arg.key == OIS::KC_Q)
		mExitGame = true;

	CEGUI::System::getSingleton().injectKeyDown(arg.key);
	CEGUI::System::getSingleton().injectChar(arg.text);

	return true;
}

bool NetState::keyReleased(const OIS::KeyEvent &arg)
{
	return true;
}

bool NetState::mouseMoved( const OIS::MouseEvent &arg )
{
	CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
	return true;
}

bool NetState::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id));
	return true;
}

bool NetState::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id));
	return true;
}

bool NetState::frameStarted(const FrameEvent& evt)
{
	if (mKeyboard) 
		mKeyboard->capture();
	if (mMouse)
		mMouse->capture();
	/*
	if (mIP) {
		CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
		CEGUI::Window *ip = wmgr->getWindow((CEGUI::utf8*)"Net/IP");
		ip->captureInput();
	}
	*/
		

	return true;
}

bool NetState::frameEnded(const FrameEvent& evt)
{
	if (mCreate || mConnect) {
		conn->update();
		CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
		CEGUI::Window *text = wmgr->getWindow((CEGUI::utf8*)"Net/Text");
		CEGUI::String tmp = text->getText();
		tmp += conn->output;
		text->setText(tmp);
	}
	
	if (mExitGame)
		changeState(IntroState::getInstance());

	/*
	if (mGoToPlay)
		changeState(PlayState::getInstance());
		*/

	if (mStart) {
		if (mCreate)
			changeState(PlayState::getInstance());
	}
	
	return true;
}

void NetState::createScene()
{
}

void NetState::setupEventHandlers()
{
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
/*
	CEGUI::Window *play = wmgr->getWindow((CEGUI::utf8*)"Intro/PlayButton");
	play->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetState::handlePlay, this));
*/
    CEGUI::Window *quit = wmgr->getWindow((CEGUI::utf8*)"Net/QuitButton");
	quit->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetState::handleQuit, this));
	CEGUI::Window *create = wmgr->getWindow((CEGUI::utf8*)"Net/CreateButton");
	create->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetState::handleCreate, this));
    CEGUI::Window *connect = wmgr->getWindow((CEGUI::utf8*)"Net/ConnectButton");
	connect->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetState::handleConnect, this));
    CEGUI::Window *start = wmgr->getWindow((CEGUI::utf8*)"Net/StartButton");
	start->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetState::handleStart, this));
    CEGUI::Window *text = wmgr->getWindow((CEGUI::utf8*)"Net/Text");
	text->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetState::handleText, this));
    CEGUI::Window *ip = wmgr->getWindow((CEGUI::utf8*)"Net/IP");
	ip->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetState::handleIP, this));
	CEGUI::Window *send = wmgr->getWindow((CEGUI::utf8*)"Net/Send");
	send->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetState::handleSend, this));

}


bool NetState::handleQuit(const CEGUI::EventArgs& e)
{
	mExitGame = true;
	return true;
}
/*
bool NetState::handlePlay(const CEGUI::EventArgs& e)
{
	mGoToPlay = true;
	return true;
}
*/

bool NetState::handleCreate(const CEGUI::EventArgs& e)
{
	string address;
	if (mCreate || mConnect)
		return false;
	
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
    CEGUI::Window *text = wmgr->getWindow((CEGUI::utf8*)"Net/Text");
	CEGUI::String tmp = text->getText();

	mCreate = conn->createServer(address);
	tmp += "\nServer created at IP: " + conn->address + "\nConnect to this address \n";
	tmp += conn->output;
	text->setText( tmp);
	mCreate = true;
	return true;
}

bool NetState::handleConnect(const CEGUI::EventArgs& e)
{
	if (mCreate || mConnect)
		return false;
	
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
    CEGUI::Window *text = wmgr->getWindow((CEGUI::utf8*)"Net/Text");
	CEGUI::String tmp = text->getText();

	CEGUI::Window *ip= wmgr->getWindow((CEGUI::utf8*)"Net/IP");
	mConnect = conn->connectTo(string(ip->getText().c_str()));

	tmp += conn->output;
	text->setText( tmp);
	mConnect = true;
	return true;
}

bool NetState::handleStart(const CEGUI::EventArgs& e)
{
	if (mConnect)
		return false;

	mStart = true;
	return true;
}

bool NetState::handleText(const CEGUI::EventArgs& e)
{

	return true;
}

bool NetState::handleIP(const CEGUI::EventArgs& e)
{
	mIP = true;
	/*
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
    CEGUI::Window *ip = wmgr->getWindow((CEGUI::utf8*)"Net/IP");
	ip->activate();
	*/
	return true;
}

bool NetState::handleSend(const CEGUI::EventArgs& e)
{
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
    CEGUI::Window *msg = wmgr->getWindow((CEGUI::utf8*)"Net/Message");
	if (!msg->getText().empty())
		conn->msg = string(msg->getText().c_str());
	msg->setText("");

	return true;
}